#!/usr/bin/python

import sys
import libxml2dom
import urllib
import datetime

from movie.vote.models import Movie

def GetTomatoScore(html):
  # <span class='fl' style='margin-left:15px; display: block; height: 50px; width: 50px;'>85</span>
  doc = libxml2dom.parseString(html, html=1)
  for n in doc.getElementsByTagName('div'):
    if n.hasAttribute('id') and n.getAttribute('id') == 'critics_tomatometer_score':
      try:
        score = int(n.childNodes[1].childNodes[0].value.strip())
      except ValueError:
        return None
      if score > 0:
        return score
  return None

def GetMetacriticScore(html):
  # <TD WIDTH="130"><IMG SRC="/_images/scores/80.gif" ALT="Metascore: 80" WIDTH="130" HEIGHT="50"></TD>
  doc = libxml2dom.parseString(html, html=1)
  for n in doc.getElementsByTagName('img'):
    if n.hasAttribute('alt') and n.getAttribute('alt').startswith('Metascore: '):
      try:
        score = int(n.getAttribute('alt').split()[1])
      except ValueError:
        return None
      if score > 0:
        return score
  return None

def GetAverageScore(movie):
  if movie.rotten_score == None and movie.metacritic_score == None:
    return None
  if movie.rotten_score == None:
    return movie.metacritic_score
  elif movie.metacritic_score == None:
    return movie.rotten_score
  else:
    return (movie.rotten_score + movie.metacritic_score) / 2.0

def UpdateMovieReviewScores(old_review_days, skip_review_days):
  """old_review_days is the number of days a review score becomes stale
  and needs to be updated.

  skip_review_days is how old a movie must be before skipping updating
  reviews. This is used to stop updating review scores for very old movies
  whole scores don't change anymore.
  """
  for movie in Movie.objects.all():
    need_save = False
    now = datetime.datetime.now()
    cutoff = datetime.date.today() - datetime.timedelta(old_review_days)
    skip_cutoff = datetime.date.today() - datetime.timedelta(skip_review_days)

    if movie.rotten_url:
      if (movie.rotten_score == None or
          (movie.rotten_score_last_updated < cutoff and
           movie.date_added > skip_cutoff)):
        try:
          rotten_score = GetTomatoScore(urllib.urlopen(movie.rotten_url).read())
        except IOError:
          pass
        else:
          if rotten_score:
            movie.rotten_score_last_updated = now
            movie.rotten_score = rotten_score
            need_save = True

    if movie.metacritic_url:
      if (movie.metacritic_score == None or
          (movie.metacritic_score_last_updated < cutoff and
           movie.date_added > skip_cutoff)):
        try:
          metacritic_score = GetMetacriticScore(urllib.urlopen(movie.metacritic_url).read())
        except IOError:
          pass
        else:
          if metacritic_score:
            movie.metacritic_score = metacritic_score
            movie.metacritic_score_last_updated = now
            need_save = True

    average = GetAverageScore(movie) 
    if average:
      if movie.review_average_score != average:
        movie.review_average_score = average
        need_save = True

    if need_save:
      print '%s meta: %s rotten: %s average: %s' % (movie, movie.metacritic_score,
                                                    movie.rotten_score, movie.review_average_score)
      movie.save()


if __name__ == '__main__':
  days_back = 5
  skip_review_days = 30
  if len(sys.argv) > 1:
    days_back = int(sys.argv[1])
  UpdateMovieReviewScores(old_review_days=days_back, skip_review_days=skip_review_days)
